#ifndef ASSEMBLER_H
#define ASSEMBLER_H
#include "global.h"
#include "opcode.h"


namespace tinyscript{
namespace internal{

class Assembler {
public:
    // A Label is a offset value from the source of the encoder, the user set
    // a label at certain duration and later reference to this label.

    class Label {
    public:
        uint32_t offset() const {
            return offset_;
        }
        int opcode() const {
            return opcode_;
        }

        Label( uint32_t offset , int op ) :
            offset_(offset),
            opcode_(op){}
    private:
        uint32_t offset_;
        int opcode_;
    };

    Label SetLabel() const;

    class T1Instruction {
    public:
        void set_opt( uint32_t opt );
        void set_lhs( uint32_t lhs );
        void set_rhs( uint32_t rhs );
    private:
        void* buffer_;
    };

    class T2Instruction {
    public:
        void set_opt( uint32_t opt );
        void set_arg( uint32_t arg );
    private:
        void* buffer_;
    };

    class T3Instruction {
    public:
        void set_opt( uint32_t opt );
        void set_value( const Value& val );
    private:
        void* buffer_;
    };

public:
    void add( uint32_t lhs , uint32_t rhs );
    T1Instruction add();

    void sub( uint32_t lhs , uint32_t rhs );
    T1Instruction sub();

    void mul( uint32_t lhs , uint32_t rhs );
    T1Instruction mul();

    void div( uint32_t lhs , uint32_t rhs );
    T1Instruction div();

    void mod( uint32_t lhs , uint32_t rhs );
    T1Instruction mod();

    void tlt( uint32_t lhs , uint32_t rhs );
    void tlt( uint32_t lhs );
    T1Instruction tlt1();
    T2Instruction tlt2();

    void tlet( uint32_t lhs , uint32_t rhs );
    void tlet( uint32_t lhs );
    T1Instruction tlet1();
    T2Instruction tlet2();

    void tgt( uint32_t lhs , uint32_t rhs );
    void tgt( uint32_t lhs );
    T1Instruction tgt1();
    T2Instruction tgt2();

    void tget( uint32_t lhs , uint32_t rhs );
    void tget( uint32_t lhs );
    T1Instruction tget1();
    T1Instruction tget2();

    void teq( uint32_t lhs , uint32_t rhs );
    void teq( uint32_t lhs );
    T1Instruction teq1();
    T2Instruction teq2();

    void tneq( uint32_t lhs , uint32_t rhs );
    void tneq( uint32_t lhs );
    T1Instruction tneq1();
    T1Instruction tneq2();



};

}// namespace internal
}// namespace tinyscript

#endif // ASSEMBLER_H
